<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<script>
    /*
    * 对象的解构赋值：
    *   对象解构赋值的原理：
    *   1.模式或结构相匹配
    *   2.属性名相同的完成赋值
    *
    *   模式或结构相匹配
    *   {} = {} //等号两边都必须是对象形式
    *
    *   属性名相同的完成赋值
    *   const {age,user} = {user:"yunmu",age:18} //这里不管顺序，属性名一致的才赋值
    *   //上面这行是简写（属性名和属性值一样，可以省略），完整写法是下面
    *   const {age:age,user:user} = {user:"yunmu",age:18} //属性名一致的完成赋值
    *
    *   //对象的属性名是字符串，但是在对象里面会默认将属性名转化为字符串，所以属性名的双引号可加可不加
    *   const {"age":age,"user":user} 与 const{age:age,user:user} 都是正确的对象表示形式
    *
    *   //注意对象完成赋值的都是两边对象中的属性值！
    *   对象1的属性名:对象1的属性值     对象2的属性名:对象2的属性值
    *   age:age                    age:18
    *   将对象2的 属性名age 所对应的 属性值18，赋值给对象1的 属性名age 所对应的 属性值age
    *
    * */

    /*
    * 对象解构赋值的默认值：
    * let obj = {
    *   user:"xx",
    *   age:18
    * }
    *
    * let obj1 = {}
    *
    * let {user,age} = obj //相当于{user,age} = {user:"xx",age:18}
    *
    * 但是以上赋值有个缺陷，如果参数不够或者传入的对象是空就会是undefined，所以需要给变量添加默认值
    * let {user = "xxx",age = 0} = obj1 //此时赋值的obj1是个空对象，则相当于如下代码
    * //{user = "xxx",age = 0} = {undefined,undefined}，此时解构赋值严格等于undefined，则变量取默认值
    *
    * */

    /*
    * 对象解构赋值的应用：
    *   1.函数参数的解构赋值：
    *
    *   以前在函数中传入一个对象，打印对象的相关属性是这样的：
    *   const logInfo = (user) => { //箭头函数接收一个对象
    *       //let user = {username:"yun",age:18} //这一行没必要写，函数内部默认执行了这一步代码
    *
    *       console.log({user.username,user.age}) //打印箭头函数接收的对象信息
    *   }
    *
    *   logInfo({username:"yun",age:18}) //函数执行，传入实参一个对象
    *
    *   现在可以用对象的结构赋值来写：
    *   const logInfo = ({username,age}) => {
    *       //let {username,age} = {username:"yun",age:18} //这一行没必要写，是函数内部默认执行的
    *
    *       console.log(username,age) //此时就可以直接通过解构赋值好的变量名来访问对象的属性
    *   }
    *
    *   logInfo({username:"yun",age:18}) //函数执行，传入实参对象
    *
    *   但是如果传入的对象是空对象或者对象属性不齐，则会打印undefined，所以需要给变量添加默认值
    *   const logInfo = ({username = “xx”,age = 0}) => {
    *       //let {username = “xx”,age = 0} = {undefined,undefined} //这一行没必要写，是函数内部默认执行的
    *
    *       console.log(username,age) //此时就可以直接通过解构赋值好的变量名来访问对象的属性
    *   }
    *
    *   logInfo({}) //此时传入一个空对象，访问不存在的属性，为undefined，则变量在解构赋值时就取默认值
    * */

    /*
    * 复杂对象下的解构赋值：模式或结构相匹配，属性名相同的完成赋值
    * const obj = {
    *   x:1,
    *   y:[2,3,4]
    *   z:{
    *       a:5,
    *       b:6
    *   }
    * }
    *
    * 如果我们想取到对象obj里面的y属性中对应的数组以及数组中的值3，和z属性中对应的对象中的b属性对应的值6
    * let{
    *   y:arr //obj是对象，所以直接找到相同y属性名，用一个arr接收obj对象y属性对应的整个数组
    *   y:[,c] //y属性对应的是数组，所以也要用数组，然后索引值也要为第二个，用逗号跳过第一个就行
    *   z:{b：six} //z属性对应的值是对象，所以要用对象，对象只需要属性名相同
    * } = obj //模式或结构相匹配，属性名相同的完成赋值
    *
    * //注意对象完成赋值的都是两边对象中的属性值！所以打印的时候要注意打印的是完成解构赋值后的属性值！
    * console.log(arr,c,six)
    * //对象1的属性名:对象1的属性值     对象2的属性名:对象2的属性值
    * //y:arr                       y:[2,3,4]
    * //将对象2的 属性名y 所对应的 属性值[2,3,4]，赋值给对象1的 属性名y 所对应的 属性值arr
    * //后面两个同理
    * */
</script>
</body>
</html>